/**
 * AnsiParser - ANSI转义序列解析器
 * 负责解析终端中的ANSI控制序列并执行相应的操作
 */
class AnsiParser {
  /**
   * 创建一个新的ANSI解析器
   * @param {CanvasTerminal} terminal - 终端实例
   */
  constructor(terminal) {
    this.terminal = terminal;
    this.state = 'normal'; // normal, escaped, csi
    this.params = [];
    this.currentParam = '';
    this.foreground = terminal.options.foreground;
    this.background = terminal.options.background;
    this.bold = false;
    this.italic = false;
    this.underline = false;
    this.savedCursorX = 0;
    this.savedCursorY = 0;
  }

  /**
   * 解析ANSI序列
   * @param {string} data - 要解析的数据
   */
  parse(data) {
    for (let i = 0; i < data.length; i++) {
      const char = data[i];
      
      switch (this.state) {
        case 'normal':
          if (char === '\x1b') {
            this.state = 'escaped';
          } else {
            this._handleNormalChar(char);
          }
          break;
          
        case 'escaped':
          if (char === '[') {
            this.state = 'csi';
            this.params = [];
            this.currentParam = '';
          } else {
            this.state = 'normal';
            this._handleNormalChar(char);
          }
          break;
          
        case 'csi':
          if (char >= '0' && char <= '9') {
            this.currentParam += char;
          } else if (char === ';') {
            this.params.push(this.currentParam === '' ? 0 : parseInt(this.currentParam, 10));
            this.currentParam = '';
          } else {
            if (this.currentParam !== '') {
              this.params.push(parseInt(this.currentParam, 10));
            }
            this._handleCSI(char, this.params);
            this.state = 'normal';
          }
          break;
      }
    }
  }

  /**
   * 检查字符是否是全角字符（中文、日文等）
   * @param {string} char - 要检查的字符
   * @returns {boolean} 是否是全角字符
   */
  _isFullWidthChar(char) {
    // 使用Unicode范围检查是否是全角字符
    const code = char.charCodeAt(0);
    
    // 中文、日文、韩文等CJK字符
    if ((code >= 0x3000 && code <= 0x9FFF) ||   // CJK统一表意文字及标点
        (code >= 0xAC00 && code <= 0xD7AF) ||   // 韩文
        (code >= 0xFF00 && code <= 0xFFEF)) {   // 全角ASCII、全角标点
      return true;
    }
    
    return false;
  }

  /**
   * 处理普通字符
   * @param {string} char - 字符
   */
  _handleNormalChar(char) {
    switch (char) {
      case '\r': // 回车
        this.terminal.cursorX = 0;
        break;
        
      case '\n': // 换行
        this.terminal.cursorY++;
        if (this.terminal.cursorY >= this.terminal.options.rows) {
          this._scrollUp();
        }
        break;
        
      case '\b': // 退格
        if (this.terminal.cursorX > 0) {
          this.terminal.cursorX--;
        }
        break;
        
      case '\x7f': // DEL字符 (Backspace键)
        // 退格键：向左移动光标并删除字符
        console.log(`处理Backspace键，当前光标位置: (${this.terminal.cursorX}, ${this.terminal.cursorY})`);
        if (this.terminal.cursorX > 0) {
          this.terminal.cursorX--;
          // 删除当前位置的字符，替换为空格
          if (this.terminal.cursorY < this.terminal.options.rows && this.terminal.cursorX < this.terminal.options.cols) {
            this.terminal.buffer[this.terminal.cursorY][this.terminal.cursorX] = {
              char: ' ',
              fg: this.foreground,
              bg: this.background,
              bold: this.bold,
              italic: this.italic,
              underline: this.underline,
              isFullWidth: false,
              cellWidth: this.terminal.asciiCharWidth
            };
            console.log(`删除位置 (${this.terminal.cursorX}, ${this.terminal.cursorY}) 的字符`);
          }
        } else {
          console.log(`Backspace键：已在行首，无法继续删除`);
        }
        break;
        
      case '\t': // 制表符
        const tabSize = 8;
        this.terminal.cursorX = Math.floor((this.terminal.cursorX + tabSize) / tabSize) * tabSize;
        if (this.terminal.cursorX >= this.terminal.options.cols) {
          this.terminal.cursorX = 0;
          this.terminal.cursorY++;
          if (this.terminal.cursorY >= this.terminal.options.rows) {
            this._scrollUp();
          }
        }
        break;
        
      default:
        // 过滤控制字符，只处理可打印的字符
        const charCode = char.charCodeAt(0);
        if (charCode >= 32 || this._isFullWidthChar(char)) {
          // 普通字符
          if (this.terminal.cursorY < this.terminal.options.rows && this.terminal.cursorX < this.terminal.options.cols) {
            // 检查是否是全角字符
            const isFullWidth = this._isFullWidthChar(char);
            
            // 存储字符到缓冲区
            this.terminal.buffer[this.terminal.cursorY][this.terminal.cursorX] = {
              char: char,
              fg: this.foreground,
              bg: this.background,
              bold: this.bold,
              italic: this.italic,
              underline: this.underline,
              isFullWidth: isFullWidth,
              cellWidth: isFullWidth ? this.terminal.fullWidthCharWidth : this.terminal.asciiCharWidth
            };
            
            // 移动光标，对于全角字符（如中文）占用一个位置
            this.terminal.cursorX++;
            
            // 处理换行
            if (this.terminal.cursorX >= this.terminal.options.cols) {
              this.terminal.cursorX = 0;
              this.terminal.cursorY++;
              if (this.terminal.cursorY >= this.terminal.options.rows) {
                this._scrollUp();
              }
            }
          }
        } else {
          // 忽略其他控制字符，防止被错误处理
          console.log(`忽略控制字符: 0x${charCode.toString(16).padStart(2, '0')}`);
        }
        break;
    }
  }

  /**
   * 处理CSI序列
   * @param {string} finalChar - 最终字符
   * @param {Array} params - 参数数组
   */
  _handleCSI(finalChar, params) {
    switch (finalChar) {
      case 'm': // SGR - 设置图形渲染
        this._handleSGR(params);
        break;
        
      case 'H': // CUP - 光标位置
      case 'f': // HVP - 水平垂直位置
        const row = (params[0] || 1) - 1;
        const col = (params[1] || 1) - 1;
        this.terminal.setCursor(col, row);
        break;
        
      case 'A': // CUU - 光标上移
        this.terminal.cursorY = Math.max(0, this.terminal.cursorY - (params[0] || 1));
        break;
        
      case 'B': // CUD - 光标下移
        this.terminal.cursorY = Math.min(this.terminal.options.rows - 1, this.terminal.cursorY + (params[0] || 1));
        break;
        
      case 'C': // CUF - 光标前进
        this.terminal.cursorX = Math.min(this.terminal.options.cols - 1, this.terminal.cursorX + (params[0] || 1));
        break;
        
      case 'D': // CUB - 光标后退
        this.terminal.cursorX = Math.max(0, this.terminal.cursorX - (params[0] || 1));
        break;
        
      case 'J': // ED - 擦除显示
        this._handleED(params[0] || 0);
        break;
        
      case 'K': // EL - 擦除行
        this._handleEL(params[0] || 0);
        break;
        
      case 's': // SCP - 保存光标位置
        this.savedCursorX = this.terminal.cursorX;
        this.savedCursorY = this.terminal.cursorY;
        break;
        
      case 'u': // RCP - 恢复光标位置
        if (this.savedCursorX !== undefined && this.savedCursorY !== undefined) {
          this.terminal.cursorX = this.savedCursorX;
          this.terminal.cursorY = this.savedCursorY;
        }
        break;
        
      case '~': // 处理带参数的特殊键
        const param = params[0] || 0;
        switch (param) {
          case 3: // Delete键
            // Delete键：删除当前光标位置的字符，不移动光标
            console.log(`处理Delete键，当前光标位置: (${this.terminal.cursorX}, ${this.terminal.cursorY})`);
            if (this.terminal.cursorY < this.terminal.options.rows && this.terminal.cursorX < this.terminal.options.cols) {
              const currentChar = this.terminal.buffer[this.terminal.cursorY][this.terminal.cursorX].char;
              if (currentChar !== ' ') {
                this.terminal.buffer[this.terminal.cursorY][this.terminal.cursorX] = {
                  char: ' ',
                  fg: this.foreground,
                  bg: this.background,
                  bold: this.bold,
                  italic: this.italic,
                  underline: this.underline,
                  isFullWidth: false,
                  cellWidth: this.terminal.asciiCharWidth
                };
                console.log(`删除位置 (${this.terminal.cursorX}, ${this.terminal.cursorY}) 的字符: '${currentChar}'`);
              } else {
                console.log(`Delete键：当前位置已经是空格，无需删除`);
              }
            } else {
              console.log(`Delete键：光标位置超出范围`);
            }
            break;
          default:
            console.log(`未处理的特殊键序列: ESC[${param}~`);
            break;
        }
        break;
    }
  }

  /**
   * 处理SGR序列 - 设置图形渲染
   * @param {Array} params - 参数数组
   */
  _handleSGR(params) {
    if (params.length === 0) {
      params = [0]; // 默认为0（重置）
    }
    
    for (let i = 0; i < params.length; i++) {
      const param = params[i];
      
      if (param === 0) {
        // 重置所有属性
        this.foreground = this.terminal.options.foreground;
        this.background = this.terminal.options.background;
        this.bold = false;
        this.italic = false;
        this.underline = false;
      } else if (param === 1) {
        // 粗体
        this.bold = true;
      } else if (param === 3) {
        // 斜体
        this.italic = true;
      } else if (param === 4) {
        // 下划线
        this.underline = true;
      } else if (param === 22) {
        // 非粗体
        this.bold = false;
      } else if (param === 23) {
        // 非斜体
        this.italic = false;
      } else if (param === 24) {
        // 非下划线
        this.underline = false;
      } else if (param >= 30 && param <= 37) {
        // 前景色
        this.foreground = this._getANSIColor(param - 30);
      } else if (param === 39) {
        // 默认前景色
        this.foreground = this.terminal.options.foreground;
      } else if (param >= 40 && param <= 47) {
        // 背景色
        this.background = this._getANSIColor(param - 40);
      } else if (param === 49) {
        // 默认背景色
        this.background = this.terminal.options.background;
      } else if (param >= 90 && param <= 97) {
        // 亮前景色
        this.foreground = this._getANSIBrightColor(param - 90);
      } else if (param >= 100 && param <= 107) {
        // 亮背景色
        this.background = this._getANSIBrightColor(param - 100);
      }
    }
  }

  /**
   * 获取ANSI标准颜色
   * @param {number} index - 颜色索引 (0-7)
   * @returns {string} 颜色代码
   */
  _getANSIColor(index) {
    const colors = [
      '#000000', // 黑
      '#CD0000', // 红
      '#00CD00', // 绿
      '#CDCD00', // 黄
      '#0000EE', // 蓝
      '#CD00CD', // 洋红
      '#00CDCD', // 青
      '#E5E5E5'  // 白
    ];
    return colors[index] || this.terminal.options.foreground;
  }

  /**
   * 获取ANSI亮色
   * @param {number} index - 颜色索引 (0-7)
   * @returns {string} 颜色代码
   */
  _getANSIBrightColor(index) {
    const brightColors = [
      '#7F7F7F', // 亮黑（灰）
      '#FF0000', // 亮红
      '#00FF00', // 亮绿
      '#FFFF00', // 亮黄
      '#5C5CFF', // 亮蓝
      '#FF00FF', // 亮洋红
      '#00FFFF', // 亮青
      '#FFFFFF'  // 亮白
    ];
    return brightColors[index] || this.terminal.options.foreground;
  }

  /**
   * 处理ED序列 - 擦除显示
   * @param {number} mode - 擦除模式
   */
  _handleED(mode) {
    switch (mode) {
      case 0: // 从光标到屏幕末尾
        // 清除当前行从光标到行尾
        for (let x = this.terminal.cursorX; x < this.terminal.options.cols; x++) {
          this.terminal.buffer[this.terminal.cursorY][x] = {
            char: ' ',
            fg: this.foreground,
            bg: this.background,
            bold: this.bold,
            italic: this.italic,
            underline: this.underline
          };
        }
        
        // 清除光标下方所有行
        for (let y = this.terminal.cursorY + 1; y < this.terminal.options.rows; y++) {
          for (let x = 0; x < this.terminal.options.cols; x++) {
            this.terminal.buffer[y][x] = {
              char: ' ',
              fg: this.foreground,
              bg: this.background,
              bold: this.bold,
              italic: this.italic,
              underline: this.underline
            };
          }
        }
        break;
        
      case 1: // 从屏幕开始到光标
        // 清除从屏幕开始到光标前一行的所有行
        for (let y = 0; y < this.terminal.cursorY; y++) {
          for (let x = 0; x < this.terminal.options.cols; x++) {
            this.terminal.buffer[y][x] = {
              char: ' ',
              fg: this.foreground,
              bg: this.background,
              bold: this.bold,
              italic: this.italic,
              underline: this.underline
            };
          }
        }
        
        // 清除当前行从开始到光标
        for (let x = 0; x <= this.terminal.cursorX; x++) {
          this.terminal.buffer[this.terminal.cursorY][x] = {
            char: ' ',
            fg: this.foreground,
            bg: this.background,
            bold: this.bold,
            italic: this.italic,
            underline: this.underline
          };
        }
        break;
        
      case 2: // 整个屏幕
        for (let y = 0; y < this.terminal.options.rows; y++) {
          for (let x = 0; x < this.terminal.options.cols; x++) {
            this.terminal.buffer[y][x] = {
              char: ' ',
              fg: this.foreground,
              bg: this.background,
              bold: this.bold,
              italic: this.italic,
              underline: this.underline
            };
          }
        }
        break;
    }
  }

  /**
   * 处理EL序列 - 擦除行
   * @param {number} mode - 擦除模式
   */
  _handleEL(mode) {
    switch (mode) {
      case 0: // 从光标到行尾
        for (let x = this.terminal.cursorX; x < this.terminal.options.cols; x++) {
          this.terminal.buffer[this.terminal.cursorY][x] = {
            char: ' ',
            fg: this.foreground,
            bg: this.background,
            bold: this.bold,
            italic: this.italic,
            underline: this.underline
          };
        }
        break;
        
      case 1: // 从行首到光标
        for (let x = 0; x <= this.terminal.cursorX; x++) {
          this.terminal.buffer[this.terminal.cursorY][x] = {
            char: ' ',
            fg: this.foreground,
            bg: this.background,
            bold: this.bold,
            italic: this.italic,
            underline: this.underline
          };
        }
        break;
        
      case 2: // 整行
        for (let x = 0; x < this.terminal.options.cols; x++) {
          this.terminal.buffer[this.terminal.cursorY][x] = {
            char: ' ',
            fg: this.foreground,
            bg: this.background,
            bold: this.bold,
            italic: this.italic,
            underline: this.underline
          };
        }
        break;
    }
  }

  /**
   * 向上滚动屏幕
   */
  _scrollUp() {
    // 移除第一行
    this.terminal.buffer.shift();
    
    // 添加新的空行到底部
    const newRow = [];
    for (let x = 0; x < this.terminal.options.cols; x++) {
      newRow.push({
        char: ' ',
        fg: this.foreground,
        bg: this.background,
        bold: this.bold,
        italic: this.italic,
        underline: this.underline,
        isFullWidth: false,
        cellWidth: this.terminal.asciiCharWidth
      });
    }
    this.terminal.buffer.push(newRow);
    
    // 保持光标在最后一行
    this.terminal.cursorY = this.terminal.options.rows - 1;
  }
}